#ifndef CMD_PARSER__CMD_PARSER_H
#define CMD_PARSER__CMD_PARSER_H

#include <list>
#include <map>
#include <memory>
#include <string>

namespace czj {
namespace util {

class Parameter;

class BoolParameter;

class VariableParameter;

class ListParameter;

class OperandParameter;

class ExtensionParameter;

class CmdParser {
private:
	const std::string cmd_;
	std::list<std::string> helpKeys_;
	std::map<int, std::unique_ptr<Parameter>> parameters_;
	std::map<int, std::unique_ptr<OperandParameter>> operandParameters_;
	std::unique_ptr<ExtensionParameter> extensionParameter_;
public:
	CmdParser(const char *_cmd);
	~CmdParser();
public:
	void bindHelpKey(const char *_key);
	bool addBool(int _id, const char *_describe);
	bool bindBoolKey(int _id, const char *_key);
	bool getBool(int _id) const;
	bool addVariable(int _id, const char *_describe, bool _nullable);
	bool bindVariableKey(int _id, const char *_key, const char *_hint = nullptr);
	bool bindVariableExpression(int _id, const char *_key, const char *_operator, const char *_hint = nullptr, const char *_default = nullptr);
	const std::string &getVariable(int _id) const;
	bool addList(int _id, const char *_describe, bool _nullable);
	bool bindListKey(int _id, const char *_key, const char *_hint = nullptr);
	bool bindListExpression(int _id, const char *_key, const char *_operator, const char *_hint = nullptr, const char *_default = nullptr);
	const std::list<std::string> &getList(int _id) const;
	void addOperand(int _id, const char *_describe, const char *_hint);
	const std::string &getOperand(int _id) const;
	void enableExtension(const char *_describe, const char *_hint);
	const std::list<std::string> &getExtension() const;
	void help() const;
	bool parse(int _length, const char *const *_arguments);
};

} // util
} // czj

#endif // CMD_PARSER__CMD_PARSER_H
